home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- /*
- * This file is used as a compiled module by Jove and also included as
- * source in recover.c
- */
- #ifndef TUNED
- # include "jove.h"
- #endif
- #include "scandir.h"
-
- #ifdef F_COMPLETION
-
- #ifdef MSDOS
- # include <dos.h>
- # include <search.h>
- #endif
-
- #ifdef UNIX
- # include <sys/stat.h>
- # ifdef M_XENIX
- # include <sys/ndir.h>
- # ifndef dirent
- # define dirent direct
- # endif
- # else
- # ifdef DIRENT
- # include <dirent.h>
- # else
- # include <sys/dir.h>
- # ifndef dirent
- # define dirent direct
- # endif
- # endif DIRENT
- # endif /* M_XENIX */
- #endif
-
- #ifdef UNIX
-
- #define DIRSIZE(entry) (strlen((entry)->d_name))
-
- #if !defined(BSD_DIR) && !defined(DIRENT)
-
- typedef struct {
- int d_fd; /* File descriptor for this directory */
- } DIR;
-
- private int
- closedir(dp)
- DIR *dp;
- {
- (void) close(dp->d_fd);
- free((char *) dp);
- return 0; /* don't know how to fail */
- }
-
- private DIR *
- opendir(dir)
- char *dir;
- {
- DIR *dp = (DIR *) emalloc(sizeof *dp);
- struct stat stbuf;
-
- if ((dp->d_fd = open(dir, 0)) == -1)
- return NULL;
- if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) {
- closedir(dp);
- return NULL; /* this isn't a directory! */
- }
- return dp;
- }
-
- private dirent *
- readdir(dp)
- DIR *dp;
- {
- static dirent dir;
-
- do {
- if (read(dp->d_fd, (UnivPtr) &dir, sizeof dir) != sizeof dir)
- return NULL;
- #if defined(elxsi) && defined(SYSV)
- /*
- * Elxsi has a BSD4.2 implementation which may or may not use
- * `twisted inodes' ... Anyone able to check?
- */
- } while (*(unsigned short *)&dir.d_ino == 0);
- #else
- } while (dir.d_ino == 0);
- #endif
-
- return &dir;
- }
-
- #endif /* ! BSD_DIR */
-
- /* Scandir returns the number of entries or -1 if the directory cannoot
- be opened or malloc fails. */
-
- int
- jscandir(dir, nmptr, qualify, sorter)
- char *dir;
- char ***nmptr;
- int (*qualify) proto((char *));
- int (*sorter) proto((UnivConstPtr, UnivConstPtr));
- {
- DIR *dirp;
- struct dirent *entry;
- char **ourarray;
- unsigned int nalloc = 10,
- nentries = 0;
-
- if ((dirp = opendir(dir)) == NULL)
- return -1;
- ourarray = (char **) emalloc(nalloc * sizeof (char *));
- while ((entry = readdir(dirp)) != NULL) {
- if (qualify != NULL && (*qualify)(entry->d_name) == 0)
- continue;
- if (nentries == nalloc) {
- ourarray = (char **) realloc((UnivPtr) ourarray, (nalloc += 10) * sizeof (char *));
- if (ourarray == NULL)
- complain("[Malloc failed: cannot scandir]");
- }
- ourarray[nentries] = (char *) emalloc(DIRSIZE(entry) + 1);
- null_ncpy(ourarray[nentries], entry->d_name, (size_t) DIRSIZE(entry));
- nentries += 1;
- }
- closedir(dirp);
- if ((nentries + 1) != nalloc)
- ourarray = (char **) erealloc((UnivPtr) ourarray,
- ((nentries + 1) * sizeof (char *)));
- if (sorter != NULL)
- qsort((UnivPtr) ourarray, nentries, sizeof (char **), sorter);
- *nmptr = ourarray;
- ourarray[nentries] = NULL; /* guaranteed NULL pointer */
-
- return nentries;
- }
-
- #endif /* UNIX */
-
- #ifdef MSDOS
- # define DIRSIZE(entry) strlen((entry).name)
-
- /* Scandir returns the number of entries or -1 if the directory cannot
- be opened or malloc fails. */
-
- unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
-
- int
- jscandir(dir, nmptr, qualify, sorter)
- char *dir;
- char ***nmptr;
- int (*qualify) proto((char *));
- int (*sorter) proto((UnivConstPtr, UnivConstPtr));
- {
- char dirname[FILESIZE];
- struct find_t entry;
- char *ptr;
- char **ourarray;
- unsigned int nalloc = 10,
- nentries = 0;
-
- strcpy(dirname, dir);
- ptr = &dirname[strlen(dirname)-1];
- if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\'))
- strcat(dirname, "*.*");
- else
- strcat(dirname, "/*.*");
-
- if (_dos_findfirst(dirname, fmask, &entry))
- return -1;
- if ((ourarray = (char **) emalloc(nalloc * sizeof (char *))) == NULL)
- do {
- if ((fmask == 0x10) && !(entry.attrib&fmask))
- continue;
- strlwr(entry.name);
- if (qualify != NULL && (*qualify)(entry.name) == 0)
- continue;
- if (nentries == nalloc) {
- ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
- if (ourarray == NULL)
- complain("[Malloc failed: cannot scandir]");
- }
- ourarray[nentries] = (char *) emalloc(DIRSIZE(entry) + 1);
- null_ncpy(ourarray[nentries], entry.name, (int) DIRSIZE(entry));
- nentries++;
- } while (_dos_findnext(&entry) == 0);
-
- if ((nentries + 1) != nalloc)
- ourarray = (char **) erealloc((char *) ourarray,
- ((nentries + 1) * sizeof (char *)));
- if (sorter != (int (*)())NULL)
- qsort((char *) ourarray, nentries, sizeof (char **), sorter);
- *nmptr = ourarray;
- ourarray[nentries] = NULL; /* guaranteed NULL pointer */
-
- return nentries;
- }
-
- #endif /* MSDOS */
-
- void
- freedir(nmptr, nentries)
- char ***nmptr;
- int nentries;
- {
- char **ourarray = *nmptr;
-
- while (--nentries >= 0)
- free((UnivPtr) *ourarray++);
- free((UnivPtr) *nmptr);
- *nmptr = NULL;
- }
-
- int
- alphacomp(a, b)
- UnivConstPtr a,
- b;
- {
- return strcmp(*(const char **)a, *(const char **)b);
- }
- #endif /* F_COMPLETION */
-